/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.lpcluster;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * Class for keywords in each web page / data point
 * @author edward
 */
public class WebPage {
	private String sFilePath;
	private Map<String,Integer> words;  // Occurrence of each keyword
	
	int nTotalWordCount = 0;
	
	/**
	 * Get short file name for display
	 * @return Short description of file
	 */
	@Override
	public String toString() {
		return sFilePath.substring(sFilePath.lastIndexOf("\\")+1,sFilePath.indexOf('.'));
	}	
	
	/**
	 * Initialize new instance
	 * @param sFilePath
	 * @throws IOException 
	 */
	private void init(String sFilePath) throws IOException {
		this.sFilePath = sFilePath;

		// Read from file removing " and trailing ;
		words = new HashMap<String,Integer>();
		BufferedReader reader = new BufferedReader(new InputStreamReader(MainActivity.singleton.getAssets().open(sFilePath)));
		String sLine = reader.readLine();
		
		// ***** LP-LOC # 1b *****
		for (int i=0; sLine!=null; sLine=reader.readLine(),i++) {
			// Skip first line containing file description
			if (i > 0) {
				int nIndex = sLine.indexOf("\"=");
				int nCount = Integer.parseInt(sLine.substring(nIndex+2,sLine.length()-1));
				words.put(sLine.substring(0,nIndex), nCount);
				nTotalWordCount += nCount;
			}
		}
		reader.close();
	}
	
	/**
	 * Factory method for instantiating by file
	 * @param sFilePath File path to the data file
	 * @return Instance of class
	 * @throws IOException if file cannot be found
	 */
	static WebPage webPageWithFilePath(String sFilePath) throws IOException {
		WebPage webPage = new WebPage();
		webPage.init(sFilePath);
		return webPage;
	}	
	
	/**
	 * Compute distance between two web pages
	 * @param another Other web page to compare with
	 * @return Distance in double precision
	 */
	double distanceWith(WebPage another) {

		// ***** LP-LOC # 5a *****
		// Compute total occurrences of common word in both pages
		int nCount = 0;
		for (String sKey : words.keySet()) {
			Integer anotherCount = another.words.get(sKey);
			if (anotherCount != null) nCount += anotherCount+words.get(sKey);
		}

		// Define distance as 1-(# of common words weighted by occurrences)
		if (nCount == 0) return 1f;
		return 1-((double)nCount/(nTotalWordCount+another.nTotalWordCount));
	}
        
	/**
	 * Factory method for combining WebPages into one instance
	 * @param webPages WebPages to combine
	 * @return Combined instance
	 */
	static WebPage webPageWithWebPages (List<WebPage> webPages) {
		WebPage superWebPage = new WebPage();
		superWebPage.words = new HashMap<String,Integer>();
		Random random = new Random(LPCluster.getSeed());
		
		// ***** LP-LOC # 6 *****
		// Aggregate documents to create SC and VC
		for (WebPage webPage : webPages) {
			if (random.nextInt(100) < Cluster.nCentroidPerf) continue;
			for (String sKey : webPage.words.keySet()) {
				if (random.nextInt(100) < Cluster.nCentroidPerf) continue;
				Integer nMyCount = superWebPage.words.get(sKey);
				int nOtherCount = webPage.words.get(sKey);
				superWebPage.words.put(sKey, (nMyCount!=null?nMyCount:0)+nOtherCount);
				superWebPage.nTotalWordCount += nOtherCount;
			}
		}
		return superWebPage;
	}
	
	/**
	 * Factory method for creating virtual WebPage with keyword sum close to nCount
	 * @param nCount Keyword count to sum up to
	 * @return Virtual WebPage
	 */
	WebPage initByCount (int nCount) {
		int nAccumulate = 0;
		Map<String,Integer> dict = new HashMap<String,Integer>(words.size()/2);
		
		// ***** LP-LOC # 7a *****
		// Sample keywords in points to create virtual WebPage
		for (String sKey : words.keySet()) {
			int nWordCount = words.get(sKey);
			nAccumulate += nWordCount;
			dict.put(sKey, nWordCount);
			if (nAccumulate >= nCount) break;
		}

		WebPage webPage = new WebPage();
		webPage.words = dict;
		return webPage;
	}
}
